package roborally.usableitems;

import be.kuleuven.cs.som.annotate.Raw;
import roborally.itemsonboard.BoardItem;
import roborally.itemsonboard.Robot;

/**
 * This interface specifies usable items that are also boardItems and that have a weight. These items can also be picked up and dropped. All methods are implemented
 * nominal. There are checkers specified on which conditions an object can be used.
 * 
 * @invar The boardItem must have a valid position at all times. (repeated)
 * 		| canHaveAsPosition(this.getPosition())
 * @invar The boardItem must have a proper board at all times. (repeated)
 * 		| hasProperBoard()
 * 
 * @invar If this item is possessed by a robot, then the board must be null.
 * 		| !this.isPossessed() || this.getBoard() == null
 * 
 * @author Molderez Tom, 2de bach Ingenieurswetenschappen Computerwetenschappen-Elektrotechniek and Reniers Jorn, 2de bach Ingenieurswetenschappen Werktuigkunde-Computerwetenschappen
 * @version 2.0
 */
public interface UsableWithBoard extends BoardItem, Usable {
	
	/**
	 * Let the robot pick up this usable, if possible.
	 * 
	 * @param robot The robot that should pick up this usable.
	 * @pre
	 * 		| robot != null
	 * @pre 
	 * 		| robot.canPickUp(this)
	 * @pre
	 * 		| !isTerminated()
	 * @pre
	 * 		| !isPossessed()
	 * @effect
	 * 		| robot.getBoard().removeAsItem(this)
	 */
	public abstract void isPickedUp(Robot robot);
	
	/**
	 * Let the robot drop this usable, if possible.
	 * 
	 * @param robot The robot that should drop this usable.
	 * @pre
	 * 		| robot != null
	 * @pre 
	 * 		| robot.canDrop(this)
	 * @pre
	 * 		| !isTerminated()
	 * @pre
	 * 		| !isPossessed()
	 * @effect 
	 * 		| if robot.getBoard() != null
	 * 		|	then robot.getBoard().addAsItem(this)
	 * @effect
	 * 		| if robot.getBoard() == null
	 * 		|	then this.setBoard(null)
	 * @post
	 * 		| (new this).getPosition() == robot.getPosition()
	 * 
	 * @note The robot will leave this method in a raw state because this usable will have a board and
	 * a position, and the robot will possess this battery.
	 */
	@Raw
	public abstract void isDropped(Robot robot);
	
}
